package com.base.vistter.iframe.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.vistter.iframe.entity.InverterAlarm;
import com.base.vistter.iframe.entity.InverterAlarmDetails;
import com.base.vistter.iframe.entity.InverterDevices;
import com.base.vistter.iframe.entity.InverterStation;
import com.base.vistter.iframe.exception.IframeException;
import com.base.vistter.iframe.mapper.InverterAlarmDetailsMapper;
import com.base.vistter.iframe.mapper.InverterAlarmMapper;
import com.base.vistter.iframe.utils.ToolUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
public class InverterAlarmDetailsService extends BaseService<InverterAlarmDetailsMapper, InverterAlarmDetails> {
    @Resource(name = "inverterDevicesService")
    private InverterDevicesService inverterDevicesService;
    @Resource(name = "inverterAlarmMapper")
    private InverterAlarmMapper inverterAlarmMapper;
    @Resource(name = "inverterStationService")
    private InverterStationService inverterStationService;

    @Transactional(readOnly = true)
    public Page<InverterAlarmDetails> pageInverterAlarmDetails(Page<InverterAlarmDetails> page, Integer status, Integer stationId) throws IframeException {
        if (ToolUtils.isAdmin() || ToolUtils.isBusAdmin()) {
            Long total = 0L;
            List<Integer> devicesIds = null;
            if (stationId != null) {
                devicesIds = inverterDevicesService.getDevicesIds(stationId);
                total = this.baseMapper.getCountInverterAlarmDetails(status, devicesIds);
            } else {
                total = this.baseMapper.getCountInverterAlarmDetails(status, null);
            }
            if (total == 0L) {
                return page;
            }
            page.setTotal(total);
            List<InverterAlarmDetails> results = this.baseMapper.getInverterAlarmDetailsList(status, devicesIds);
            page.setRecords(results);
            return page;
        } else {
            List<Integer> devicesIds = null;
            if (stationId != null) {
                devicesIds = inverterDevicesService.getDevicesIds(stationId);
            } else {
                List<InverterDevices> devices = inverterDevicesService.getMyDevices();
                if (devices == null || devices.isEmpty()) {
                    return page;
                }
                devicesIds = devices.stream().map(InverterDevices::getId).toList();
            }

            Long total = this.baseMapper.getCountInverterAlarmDetails(status, devicesIds);
            if (total == 0L) {
                return page;
            }
            page.setTotal(total);
            List<InverterAlarmDetails> records = this.baseMapper.getInverterAlarmDetailsList(status, devicesIds);
            page.setRecords(records);
            return page;
        }
    }

    @Transactional(readOnly = true)
    public InverterAlarmDetails getInverterAlarmDetailsById(Integer id) {
        return this.baseMapper.getInverterAlarmDetailsById(id);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Boolean recover(Integer alarmId) throws IframeException {
        InverterAlarmDetails inverterAlarmDetails = super.getById(alarmId);
        inverterAlarmDetails.setEndTime(new Date());
        inverterAlarmDetails.setStatus(2);
        super.updateById(inverterAlarmDetails);

        LambdaQueryWrapper<InverterAlarmDetails> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(InverterAlarmDetails::getInverterDevicesId, inverterAlarmDetails.getInverterDevicesId()).eq(InverterAlarmDetails::getStatus, 1);
        List<InverterAlarmDetails> list = super.selectList(lambdaQueryWrapper);
        if (list == null || list.isEmpty()) {
            LambdaQueryWrapper<InverterAlarm> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(InverterAlarm::getInverterDevicesId, inverterAlarmDetails.getInverterDevicesId());
            InverterAlarm inverterAlarm = inverterAlarmMapper.selectOne(queryWrapper);
            inverterAlarm.setEndTime(new Date());
            inverterAlarm.setStatus(2);
            inverterAlarmMapper.updateById(inverterAlarm);
        }
        return true;
    }

    @Transactional(readOnly = true)
    public List<InverterAlarmDetails> getByDevicesId(Integer devicesId) {
        return super.getBaseMapper().getByDevicesId(devicesId);
    }

    @Transactional(readOnly = true)
    public Page<InverterAlarmDetails> pageAlarmDetails(Page<InverterAlarmDetails> page, Integer status, Date beginTime, Date endTime, Integer stationId) throws IframeException {
        long total = 0L;
        List<Integer> ids = new ArrayList<Integer>();
        if (stationId != null) {
            ids.add(stationId);
        } else {
            if (ToolUtils.isNormalUser()) {
                ids = inverterStationService.myStation().stream().map(InverterStation::getId).toList();
                if (ids.isEmpty()) {
                    return page;
                }
            }
        }
        total = this.baseMapper.pageAlarmDetailsCount(status, beginTime, endTime, ids);
        if (total == 0L) {
            return page;
        }
        page.setTotal(total);
        long start = (page.getCurrent() - 1) * page.getSize();
        long size = page.getSize();
        List<InverterAlarmDetails> records = this.baseMapper.pageAlarmDetails(status, beginTime, endTime, ids, start, size);
        page.setRecords(records);
        return page;
    }

    @Transactional(readOnly = true)
    public List<InverterAlarmDetails> downloadList(Integer status, Date beginTime, Date endTime) throws IframeException {
        List<Integer> ids = null;
        if (ToolUtils.isNormalUser()) {
            ids = inverterStationService.myStation().stream().map(InverterStation::getId).toList();
            if (ids.isEmpty()) {
                return new ArrayList<InverterAlarmDetails>();
            }
        }
        return this.baseMapper.pageAlarmDetails(status, beginTime, endTime, ids, 0L, 100000L);
    }

    @Transactional(readOnly = true)
    public List<InverterAlarmDetails> getListByAlarmId(Integer inverterAlarmId) throws IframeException{
        return this.baseMapper.getListByAlarmId(inverterAlarmId);
    }

}
